﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.PlottingServices;

namespace cadbom
{
    public class PreviewCommands
    {
        [CommandMethod("simprev")]
        static public void SimplePreview()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            // PlotEngines do the previewing and plotting
            if (PlotFactory.ProcessPlotState ==  ProcessPlotState.NotPlotting)
            {
                // First we preview...
                PreviewEndPlotStatus stat;
                PlotEngine pre = PlotFactory.CreatePreviewEngine((int)PreviewEngineFlags.Plot);

                using (pre)
                {
                    stat = PlotOrPreview( pre, true, db.CurrentSpaceId,  "" );
                }
                if (stat == PreviewEndPlotStatus.Plot)
                {
                    // And if the user asks, we plot...
                    PlotEngine ple =  PlotFactory.CreatePublishEngine();
                    stat =  PlotOrPreview(  ple, false, db.CurrentSpaceId,"c:\\previewed-plot\\aa.pdf"   );
                }
            }
            else
            {
                ed.WriteMessage( "\nAnother plot is in progress."  );
            }
        }
        
        static PreviewEndPlotStatus PlotOrPreview( PlotEngine pe, bool isPreview, ObjectId spaceId, string filename)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            PreviewEndPlotStatus ret =  PreviewEndPlotStatus.Cancel;
            Transaction tr =  db.TransactionManager.StartTransaction();
            using (tr)
            {
                // We'll be plotting the current layout
                BlockTableRecord btr =  (BlockTableRecord)tr.GetObject( spaceId, OpenMode.ForRead);

                Layout lo = (Layout)tr.GetObject( btr.LayoutId, OpenMode.ForRead  );
                // We need a PlotInfo object
                // linked to the layout
                PlotInfo pi = new PlotInfo();
                pi.Layout = btr.LayoutId;

                // We need a PlotSettings object
                // based on the layout settings
                // which we then customize

                PlotSettings ps =  new PlotSettings(lo.ModelType);
                ps.CopyFrom(lo);                
                // The PlotSettingsValidator helps
                // create a valid PlotSettings object
                ps.ShowPlotStyles = true;
                PlotSettingsValidator psv = PlotSettingsValidator.Current;
                
                // We'll plot the extents, centered and
                // scaled to fit
                psv.SetPlotType(   ps,  Autodesk.AutoCAD.DatabaseServices.PlotType.Extents  );
                psv.SetUseStandardScale(ps, true);
                psv.RefreshLists(ps);
                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
                psv.SetPlotRotation(ps, PlotRotation.Degrees090);
                psv.SetCurrentStyleSheet(ps, "monochrome.ctb");
                psv.SetPlotCentered(ps, true);
                // We'll use the standard DWF PC3, as
                // for today we're just plotting to file
                psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", "ISO_full_bleed_A4_(210.00_x_297.00_MM)");

                // We need to link the PlotInfo to the
                // PlotSettings and then validate it
                pi.OverrideSettings = ps;
                PlotInfoValidator piv =  new PlotInfoValidator();
                piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
                piv.Validate(pi);
                // Create a Progress Dialog to provide info
                // and allow thej user to cancel
                PlotProgressDialog ppd =  new PlotProgressDialog(isPreview, 1, true);

                using (ppd)
                {
                    ppd.set_PlotMsgString(  PlotMessageIndex.DialogTitle, "Custom Preview Progress"         );
                    ppd.set_PlotMsgString(    PlotMessageIndex.SheetName,   doc.Name.Substring( doc.Name.LastIndexOf("\\") + 1 ) );
                    ppd.set_PlotMsgString(      PlotMessageIndex.CancelJobButtonMessage,"Cancel Job"          );
                    ppd.set_PlotMsgString(      PlotMessageIndex.CancelSheetButtonMessage,  "Cancel Sheet"             );
                    ppd.set_PlotMsgString(          PlotMessageIndex.SheetSetProgressCaption,  "Sheet Set Progress"     );
                    ppd.set_PlotMsgString(         PlotMessageIndex.SheetProgressCaption,               "Sheet Progress"            );
                    ppd.LowerPlotProgressRange = 0;
                    ppd.UpperPlotProgressRange = 100;
                    ppd.PlotProgressPos = 0;
                    // Let's start the plot/preview, at last
                    ppd.OnBeginPlot();
                    ppd.IsVisible = true;
                    pe.BeginPlot(ppd, null);
                    // We'll be plotting/previewing
                    // a single document
                    pe.BeginDocument(   pi,  doc.Name,   null,  1,  !isPreview,filename    );
                    // Which contains a single sheet
                    ppd.OnBeginSheet();
                    ppd.LowerSheetProgressRange = 0;
                    ppd.UpperSheetProgressRange = 100;
                    ppd.SheetProgressPos = 0;
                    PlotPageInfo ppi = new PlotPageInfo();
                    pe.BeginPage(                   ppi,               pi,         true,           null    );
                    pe.BeginGenerateGraphics(null);
                    ppd.SheetProgressPos = 50;
                    pe.EndGenerateGraphics(null);
                    // Finish the sheet
                    PreviewEndPlotInfo pepi =   new PreviewEndPlotInfo();
                    pe.EndPage(pepi);
                    ret = pepi.Status;
                    ppd.SheetProgressPos = 100;
                    ppd.OnEndSheet();
                    
                    // Finish the document                    
                    pe.EndDocument(null);
                    // And finish the plot
                    ppd.PlotProgressPos = 100;
                    ppd.OnEndPlot();
                    pe.EndPlot(null);
                }
                // Committing is cheaper than aborting
                tr.Commit();
            }
            return ret;
        }

    }
}
